原数组对象
// list: 数组对象
// id: 每条数据的id
// pid: 每条数据的父节点对应字段
// pid:null 没有父节点的数据
const list = [
{ id: 04, pid: 03 },
{ id: 01, pid: null },
{ id: 02, pid: null },
{ id: 03, pid: 01 },
{ id: 05, pid: 01 },
{ id: 06, pid: 03 },
{ id: 07, pid: 02 },
{ id: 09, pid: 02 },
{ id: 10, pid: 07 },
]
复制代码
转换为树形结构
[
{
"id": 1,
"pid": null,
"children": [
{
"id": 3,
"pid": 1,
"children": [
{
"id": 4,
"pid": 3
},
{
"id": 6,
"pid": 3
}
]
},
{
"id": 5,
"pid": 1
}
]
},
{
"id": 2,
"pid": null,
"children": [
{
"id": 7,
"pid": 2,
"children": [
{
"id": 10,
"pid": 7
},
{
"id": 11,
"pid": 7
}
]
},
{
"id": 9,
"pid": 2
}
]
}
]
复制代码
思路:将有父子关系的数组数据先分为两类,一类是没有父节点的数据(parent),另一类是有父节点的数据(children),然后通过遍历parent,对每一个父节点在children查找对应的子节点,并将其放入父节点的children中(这里我的是以children表示子节点),然后每个子节点又作为一个父节点来重复之前的动作。
方法一:
function toTree(data) {
let result = []
//如果值是 Array,则为true; 否则为false。
if(!Array.isArray(data)) {
return result
}
//根据父节点进行拼接子节点,
data.forEach(item => {
console.log(item);
delete item.children; //已经有的话就删掉
});
//把每一项的引用放入map对象里
let map = {};
data.forEach(item => {
map[item.id] = item;
});
//再次遍历数组 决定item的去向
data.forEach(item => {
let parent = map[item.pid];
if(parent) {
// 如果 map[item.pid] 有值 则 parent 为 item 的父级
// 判断 parent 里有无children 如果没有则创建 如果有则直接把 item push到children里
(parent.children || (parent.children = [])).push(item);
} else {
// 如果 map[item.pid] 找不到值 说明此 item 为 第一级
result.push(item);
}
});
return result;
}
console.log(toTree(list))
复制代码
方法二:
function toTree(data) {
let result = [];
let obj = {};
data.forEach(item => {
obj[item.id] = Object.assign(item, obj[item.id] || {});
if (item.pid) {
let parent = obj[item.pid] || {};
parent.child = parent.child || [];
parent.child.push(item);
obj[item.pid] = parent;
} else {
result.push(obj[item.id])
}
})
return result;
}
console.log(toTree(list))
复制代码
|